<template>
	<div>
		<el-table
			:data="tableData"
			style="width: 100%; margin-bottom: 20px"
			row-key="numIdx"
			border
			:indent="1"
			:default-expand-all="defaultExpandAll"
			show-summary
			:summary-method="getSummaries"
			@cell-click="handleCellClick"
		>
			<!--    <el-table-column type="index" label="序号" width="60" align="center" />-->
			<el-table-column prop="numIdx" label="序号" width="100"></el-table-column>
			<el-table-column prop="name" label="费用名称">
				<template #default="scope">
					<el-input
						v-if="tableType === 'edit' && activeCell === scope.row.numIdx"
						:id="`RefInput${scope.row.numIdx}`"
						:autofocus="true"
						:clearable="true"
						@blur="() => (activeCell = 0)"
						v-model="scope.row.name"
					/>
					<span v-else>{{ scope.row.name }}</span>
				</template>
			</el-table-column>
			<el-table-column prop="amount" label="费用金额（万元）">
				<template #default="scope">
					<el-input
						:controls="false"
						@keydown="(e:Event)=>keyDown(e,scope.row)"
						@keyup="(e:Event)=>keyUp(e,scope.row)"
						v-if="tableType === 'edit'"
						v-model="scope.row.amount"
						@blur="(e:Event)=>calcChildren(e,scope.row)"
						:disabled="scope.row.children && scope.row.children.length > 0"
					>
					</el-input>
					<span v-else>{{ scope.row.amount }}</span>
				</template>
			</el-table-column>
			<el-table-column prop="remark" label="备注">
				<template #default="scope">
					<el-input v-if="tableType === 'edit'" v-model="scope.row.remark" :maxlength="200"></el-input>
					<span v-else>{{ scope.row.remark }}</span>
				</template>
			</el-table-column>
			<el-table-column v-if="tableType === 'edit'" prop="address" label="操作" align="center" width="240">
				<template #header>
					操作<el-button type="primary" icon="Plus" style="margin-left: 20px" v-if="tableData.length == 0" @click="handleAddInit">新增</el-button>
				</template>
				<template #default="{ row }">
					<el-button link type="primary" size="small" @click="handleClick(row.numIdx)">新增同级费用</el-button>
					<el-button link type="primary" size="small" @click="handleDownClick(row.numIdx)">新增下级费用</el-button>
					<el-button link type="primary" size="small" @click="handleDel(row.numIdx)">删除</el-button>
				</template>
			</el-table-column>
		</el-table>
	</div>
</template>

<script lang="ts">
import { defineComponent, ref, toRefs, nextTick, watch } from 'vue';
import { ElMessageBox } from 'element-plus';

export default defineComponent({
	name: 'BudgetDetailsTable',
	props: {
		tableType: {
			type: String,
			default: 'edit',
		},
		tableData: {
			type: Array,
			default: () => [],
		},
		defaultExpandAll: {
			type: Boolean,
			default: false,
		},
	},
	setup(props, { emit }) {
		const activeCell = ref(0);
		const activeRow = ref(null);
		const { tableData } = toRefs(props);

		watch(
			() => tableData.value,
			(val) => {
				emit('updateTable', val);
			},
			{ immediate: true, deep: true }
		);

		function getSummaries(param) {
			let sum = 0;
			function calculateSum(data) {
				data.forEach((item) => {
					if (item.amount && item.parentNumIdx == 0) {
						sum += Number(item.amount);
					}
					if (item.children) {
						calculateSum(item.children);
					}
				});
			}
			calculateSum(param.data);
			let val = sum.toString();
			let idxArr = val.split('.');
			if (idxArr.length > 1) {
				let len = idxArr[1].length;
				if (len > 6) {
					sum = sum.toFixed(6);
				} else {
					sum = sum.toFixed(len);
				}
			}
			// 尾部合计事件-值
			emit('tableSummaries', sum);
			return ['应用总资金', '--', sum, '--', '--'];
		}
		function handleCellClick(row, column, cell, event) {
			activeRow.value = row;
			if (column.property === 'name') {
				activeCell.value = row.numIdx;
				nextTick(() => {
					if (props.tableType == 'edit') {
						document.getElementById(`RefInput${row.numIdx}`).focus();
					}
				});
			}
		}
		function handleClick(numIdx) {
			setTimeout(() => {
				// addNode(tableData.value, activeRow.value.numIdx)
				addNode(tableData.value, numIdx);
			}, 0);
		}
		function handleDownClick(numIdx) {
			setTimeout(() => {
				// addNode(tableData.value, activeRow.value.numIdx, 'down')
				addNode(tableData.value, numIdx, 'down');
			}, 0);
		}
		function handleAddInit() {
			tableData.value.push({
				numIdx: '1',
				parentNumIdx: '0',
				name: '',
				amount: null,
				remark: '',
			});
		}
		function addNode(tree, nodeId, type = 'up') {
			for (let i = 0; i < tree.length; i++) {
				if (tree[i].numIdx === nodeId) {
					if (!tree[i].children) {
						tree[i].children = [];
					}
					if (type === 'down') {
						let _idx = 1;
						if (tree[i].children && tree[i].children.length) {
							let _idxArr = tree[i].children[tree[i].children.length - 1].numIdx.split('.');
							_idx = Number(_idxArr[_idxArr.length - 1]) + 1;
						} else {
							tree[i].amount = 0;
							let parentNumIdx = tree[i].numIdx.split('.')[0];
							calcParentAmount(parentNumIdx);
						}
						tree[i].children.push({
							// numIdx: `${tree[i].numIdx}.${tree[i].children.length + 1}`,
							numIdx: `${tree[i].numIdx}.${_idx}`,
							parentNumIdx: `${tree[i].numIdx}`,
							name: '',
							amount: null,
							remark: '',
						});
					} else {
						let idx = tree[tree.length - 1].numIdx.split('.');
						idx[idx.length - 1] = Number(idx[idx.length - 1]) + 1;
						idx = idx.join('.');
						tree.push({
							numIdx: idx,
							parentNumIdx: idx.indexOf('.') > -1 ? idx.substr(0, idx.length - 2) : '0',
							name: '',
							amount: null,
							remark: '',
						});
					}
					return;
				}
				if (tree[i].children) {
					addNode(tree[i].children, nodeId, type);
				}
			}
		}
		function calcChildren(e: Event, row: any) {
			let parentNumIdx = row.numIdx.split('.')[0];
			calcParentAmount(parentNumIdx);
		}
		function calcParentAmount(idx) {
			let parentSum = 0; //计算最上级数值
			let row: any;
			tableData.value.forEach((item) => {
				if (item.numIdx == idx) {
					row = item;
					if (item.children && item.children.length) {
						calculateParentSum(item.children);
					} else {
						parentSum = item.amount;
					}
				}
			});
			function calculateParentSum(data) {
				data.forEach((item) => {
					if (item.children && item.children.length) {
						calculateParentSum(item.children);
						item.amount = 0; //计算当前级别
						item.children.forEach((subItem) => {
							item.amount += Number(subItem.amount);
						});
					} else {
						//去除有子级的数据
						if (item.amount) {
							parentSum += Number(item.amount);
						}
					}
				});
			}
			row.amount = parentSum;
		}
		function removeNode(tree, nodeId) {
			for (let i = 0; i < tree.length; i++) {
				if (tree[i].numIdx === nodeId) {
					let parentNumIdx = tree[i].numIdx.split('.')[0];
					tree.splice(i, 1);
					calcParentAmount(parentNumIdx);
					return;
				}
				if (tree[i].children) {
					removeNode(tree[i].children, nodeId);
				}
			}
		}
		function handleDel(numIdx) {
			setTimeout(() => {
				ElMessageBox.confirm('是否删除该条数据？', '提示', { confirmButtonText: '确定', cancelButtonText: '取消', type: 'warning' })
					.then(() => {
						// removeNode(tableData.value, activeRow.value.numIdx)
						removeNode(tableData.value, numIdx);
					})
					.catch(() => {});
			}, 0);
		}
		function keyUp(e: any, row: any) {
			const reg = /^(0|[1-9]\d{0,5})(\.\d{0,6})?$/;
			const regx = /((0|[1-9]\d{0,5})(\.\d{0,6})?)/g;
			let value = e.target.value.toString();
			if (value && !reg.test(value)) {
				e.target.value = value.match(regx) ? value.match(regx)[0] : '';
				row.amount = value.match(regx) ? value.match(regx)[0] : '';
				return false;
			} else {
				return true;
			}
		}
		function keyDown(e: any, row: any) {
			let keyCode = e.which || e.keyCode;
			if ((keyCode >= 48 && keyCode <= 57) || (keyCode >= 96 && keyCode <= 105)) {
				if (row.amount) {
					row.amount = row.amount.toString() == '0' ? '' : row.amount;
				}
				return true;
			} else if (
				keyCode == 8 ||
				keyCode == 46 ||
				keyCode == 37 ||
				keyCode == 39 ||
				keyCode == 88 ||
				keyCode == 65 ||
				keyCode == 67 ||
				keyCode == 86 ||
				keyCode == 190 ||
				keyCode == 110
			) {
				return true;
			} else {
				e.preventDefault();
				return false;
			}
		}

		return {
			activeCell,
			handleAddInit,
			handleCellClick,
			handleClick,
			handleDownClick,
			handleDel,
			getSummaries,
			keyDown,
			keyUp,
			calcChildren,
		};
	},
});
</script>

<style scoped lang="scss">
:deep(.el-input-number .el-input__inner) {
	text-align: left;
}
</style>
